/*-----------------------------------------------------------------------
								 \\\|///
							   \\  - -  //
								(  @ @  )  
+-----------------------------oOOo-(_)-oOOo-----------------------------+
CONFIDENTIAL IN CONFIDENCE
This confidential and proprietary software may be only used as authorized
by a licensing agreement from CrazyBingo (Thereturnofbingo).
In the event of publication, the following notice is applicable:
Copyright (C) 2012-20xx CrazyBingo Corporation
The entire notice above must be reproduced on all authorized copies.
Author				:		CrazyBingo
Technology blogs 	: 		http://blog.chinaaet.com/crazybingo
Email Address 		: 		thereturnofbingo@gmail.com
Filename			:		spi_transfer
Data				:		2013-02-21
Description			:		Transfer SPI Data to mcu..
Modification History	:
Data			By			Version			Change Description
=========================================================================
13/02/21		CrazyBingo	1.0				Original
13/10/17		CrazyBingo	2.0				Original
-------------------------------------------------------------------------
|                                     Oooo								|
+-------------------------------oooO--(   )-----------------------------+
                               (   )   ) /
                                \ (   (_/
                                 \_)
-----------------------------------------------------------------------*/   
/***************************************************************************
	//mcu spi interface
	input			spi_cs,		//Chip select enable, default:L
	input			spi_sck	,	//Data transfer clock
	input			spi_mosi,	//Master output and slave input
	input			spi_miso,	//Master input and slave output	
***************************************************************************/

`timescale 1ns/1ns
module spi_transfer
(
	//global clock
	input				clk,
	input				rst_n,
	
	//mcu spi interface
	input				spi_cs,		//Chip select enable, default:L
	input				spi_sck	,	//Data transfer clock
//	input				spi_mosi,	//Master output and slave input
	output	reg			spi_miso,	//Master input and slave output

	//user interface		
	input				txd_en,		//Transfer enable
	input		[7:0]	txd_data,	//Transfer data
	output	reg			txd_flag	//Transfer complete signal
);

//-------------------------------------
//mcu data sync to fpga
reg	spi_cs_r0, 		spi_cs_r1;		
reg	spi_sck_r0,		spi_sck_r1;		//fsmc default 0; 8080 default 1; spi default 1;
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		begin
		spi_cs_r0 <= 1;		spi_cs_r1 <= 1;		//chip select enable
		spi_sck_r0 <= 0;	spi_sck_r1 <= 0;	//data transfer clock
		end
	else
		begin
		spi_cs_r0 <= spi_cs;		spi_cs_r1 <= spi_cs_r0;
		spi_sck_r0 <= spi_sck; 		spi_sck_r1 <= spi_sck_r0;
		end
end
wire	mcu_cs = spi_cs_r1;	
wire	mcu_write_flag = (spi_sck_r1 & ~spi_sck_r0) ? 1'b1 : 1'b0;	//nededge of sck
wire	mcu_write_done = (~spi_cs_r1 & spi_cs_r0) ? 1'b1 : 1'b0;	//posedge of cs


//-------------------------------------
//shift signal, transfer data
localparam	SPI_MISO_DEFAULT = 1'b1;
localparam	T_IDLE	=	1'b0;	//test the flag to transfer data
localparam	T_SEND	=	1'b1;	//spi transfer data
reg	[1:0]	txd_state;
reg	[3:0]	txd_cnt;
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		begin
		spi_miso <= SPI_MISO_DEFAULT;
		txd_cnt <= 0;
		txd_state <= 0;
		end
	else
		begin
		case(txd_state)
		T_IDLE:	//test the flag to transfer data
			begin
			spi_miso <= SPI_MISO_DEFAULT;
			txd_cnt <= 0;
			if(txd_en)
				txd_state <= T_SEND;
			else
				txd_state <= T_IDLE;
			end	
		T_SEND:	//spi transfer data
			begin
			if(mcu_write_done == 1'b1)
				txd_state <= T_IDLE;
			else
				txd_state <= T_SEND;
				
			if(mcu_cs == 1'b0)
				begin
				if(mcu_write_flag)		//spi sck negedge
					begin
					spi_miso <= txd_data[3'd7 - txd_cnt[2:0]];
					txd_cnt <= txd_cnt + 1'b1;
					end
				else
					begin
					spi_miso <= spi_miso;
					txd_cnt <= txd_cnt;
					end
				end
			else
				begin
				spi_miso <= SPI_MISO_DEFAULT;
				txd_cnt <= 0;
				end
			end
		endcase
		end
end


//-------------------------------------------------
//output spi transfer flag
always@(posedge clk or negedge rst_n)
begin
	if(!rst_n)
		txd_flag <= 0;
	else 
		txd_flag <= mcu_write_done;
end


endmodule

